package com.ray.controller;

import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.annotation.SaMode;
import cn.dev33.satoken.session.SaSession;
import cn.dev33.satoken.session.TokenSign;
import cn.dev33.satoken.stp.StpUtil;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.ray.controller.base.BaseController;
import com.ray.log.WebLog;
import com.ray.model.AccountWrap;
import com.ray.model.User;
import com.ray.util.JsonKit;
import com.ray.util.Ret;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/")
public class MainController extends BaseController {

    /**
     * @note 登录
     * @time 2024年03月22日 11:02:32
     * @author Ray
     */
    @RequestMapping("login")
    @WebLog(description = "请求登录接口")
    public Ret login(@RequestBody Map loginInfo) {
        User user = User.dao.findFirst("select * from user where userid = ? and region = ?",loginInfo.get("userid"),loginInfo.get("region"));
        if (user == null)
            return Ret.fail("用户名不存在");
        if (!user.getStr("password").equals(loginInfo.get("password")))
            return Ret.fail("密码错误");
        if(user.getInt("statu") == 0)
            return Ret.fail("该用户已被禁用");
        //验证账套信息
        AccountWrap aw = AccountWrap.dao.findFirst("select * from account_wrap where no = ? and pass = ? and region = ?",loginInfo.get("account_wrap"),loginInfo.get("account_wrap_pass"),loginInfo.get("region"));
        if (aw == null)
            return Ret.fail("账套信息不存在");
        StpUtil.login(user.getId(),"PC-web");
        StpUtil.getSession().set("user",user);
        StpUtil.getSession().set("account_wrap",aw);
        return Ret.ok("token",StpUtil.getTokenValue());
    }

    /**
     * @note 获取用户信息
     * @time 2024年03月22日 11:02:32
     * @author Ray
     */
    @RequestMapping("getUserinfo")
    @WebLog(description = "请求获取用户信息接口")
    public Ret getUserinfo() {
        Record res = user().toRecord();
        Record roles = null;
        Record permissions = null;
        if(user().getBoolean("is_coder")) {
            roles = new Record().set("roles", "coder");
            permissions = Db.use(base).findFirst("SELECT group_concat(no) as nos FROM permissions");
        }else {
            roles = Db.use(base).findFirst("SELECT GROUP_CONCAT(role_no) AS roles"
                    + " FROM user_role WHERE userid = ? AND region = ?",user().get("userid"),user().getStr("region"));
            permissions = Db.use(base).findFirst("SELECT group_concat(no) as nos FROM permissions t1"
                    + " LEFT JOIN role_permission t2 ON t1.no = t2.permission_no"
                    + " LEFT JOIN user_role t3 ON t2.role_no = t3.role_no"
                    + " WHERE t3.userid = ?",user().getStr("userid"));
        }
        res.set("roles", roles.getStr("roles").split(","));
        res.set("permissions", permissions.getStr("nos"));
        res.set("account_wrap",(AccountWrap) StpUtil.getSession().get("account_wrap"));
        return Ret.ok("userinfo", JsonKit.toJson(res));
    }

    @RequestMapping("logout")
    @WebLog(description = "注销登录")
    public Ret logout(){
        StpUtil.logout();
        return Ret.ok("msg","注销成功");
    }

    /**
     * @note 在线用户列表
     * @time 2024年04月07日 12:46:20
     * @author Ray
     */
    @RequestMapping("getOnlineUser")
    @WebLog(description = "在线用户列表")
    @SaCheckRole(value = {"coder","admin"},mode = SaMode.OR)
    public Ret getOnlineUser() {
        List<Record> list = new ArrayList<Record>();
        // 获取所有登录的用户ids
        List<String> logIds = StpUtil.searchSessionId("", 0, -1, false);
        // 便利获取登录信息
        SaSession session = null;
        for (int i = 0;i < logIds.size(); i++) {
            session = StpUtil.getSessionBySessionId(logIds.get(i));
            List<TokenSign> tokenSignList = session.getTokenSignList();
            for (int j = 0; j < tokenSignList.size(); j++){
                Record temp = session.getModel("user", User.class).toRecord();
                temp.set("token",tokenSignList.get(j).getValue());
                temp.set("login_type",tokenSignList.get(j).getDevice());
                temp.set("login_time",new Date(session.getCreateTime()));
                list.add(temp);
            }
        }
        return Ret.ok("msg", "成功").setJson("list", list);
    }

    /**
     * @note 强制下线
     * @time 2024年04月07日 13:18:58
     * @author Ray
     */
    @SaCheckRole(value = {"coder","admin"},mode = SaMode.OR)
    @RequestMapping("kickout")
    @WebLog(description = "强制下线")
    public Ret kickout(String token) {
        StpUtil.kickoutByTokenValue(token);
        return Ret.ok("msg", "下线成功");
    }

    /**
     * @note 强制下线
     * @time 2024年04月07日 13:18:58
     * @author Ray
     */
    @SaCheckRole(value = {"coder","admin"},mode = SaMode.OR)
    @RequestMapping("disable")
    @WebLog(description = "封禁")
    public Ret disable(String token) {
        StpUtil.kickoutByTokenValue(token);
        return Ret.ok("msg", "下线成功");
    }

}
